import functools
import threading

from flask import jsonify
from src.config import config
from redis import Redis
import time
import redis
from functools import wraps


myredis = Redis(host=config.REDIS_HOST, port=config.REDIS_PORT,password=config.REDIS_PASSWORD, db=0)
def delayfunc():
    def wrapper(f):
        def delay(*args, **kwargs):
            try:
                t = threading.Thread(target=f, args=(*args,),kwargs=kwargs)
                t.daemon = True
                t.start()
            except Exception as e:
                print(f'执行{f.__name__}，参数:{args},{kwargs}，出错:{e}')
        f.delay = delay
        return f
    return wrapper

def checkResponseJson(f):
    @functools.wraps(f)
    def wrapper(self,*args, **kwargs):
        response = f(self,*args, **kwargs)
        result = response.json()
        if isinstance(result,dict) and result.get('code') == 401:
            self.reLogin()
            result = f(self,*args, **kwargs)
            return result.json()
        else:
            return result
    return wrapper

def tryCatch(f):
    @functools.wraps(f)
    def wrapper(*args, **kwargs):
        try:
            return f(*args, **kwargs)
        except Exception as e:
            print(f'执行{f.__name__}，参数:{args},{kwargs}，出错:{e}')
            return jsonify({"error":str(e)})

    return wrapper



# 连接到Redis服务器
r = redis.StrictRedis(host='localhost', port=6379, db=0)

def rate_limit(limit, per_second):
    """
    限流装饰器，使用令牌桶算法。
    
    :param limit: 每秒允许的最大请求数。
    :param per_second: 时间窗口大小（秒）。
    """
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            # 定义Redis键名
            key = f"rate_limit:{func.__name__}"
            
            # 尝试获取令牌
            now = time.time()
            timestamp = myredis.get(key + ':timestamp')
            tokens = float(myredis.get(key) or limit)

            if timestamp is not None:
                elapsed = now - float(timestamp)
                # 根据经过的时间补充令牌
                tokens += elapsed * (limit / per_second)
                
            tokens = min(limit, tokens)  # 不让令牌超过上限
            
            if tokens >= 1:
                # 如果有足够的令牌，则消耗一个令牌并更新时间戳
                tokens -= 1
                pipe = myredis.pipeline()
                pipe.set(key, tokens)
                pipe.set(key + ':timestamp', now)
                pipe.execute()
                
                return func(*args, **kwargs)
            else:
                # 如果没有足够的令牌，拒绝请求
                return f"每{per_second}秒允许请求{limit}次，超过次数限制", 429  # HTTP 429 Too Many Requests
            
        return wrapper
    return decorator

class TestLogger():
    def __init__(self,):
        pass
    def info(self,msg):
        print(msg)
    def debug(self,msg):
        print(msg)
    def error(self,msg):
        print(msg)
    def warning(self,msg):
        print(msg)
    